package by.bsu.touragency.command.admin;

import java.util.GregorianCalendar;
import java.util.Scanner;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;

import by.bsu.touragency.db.beans.City;
import by.bsu.touragency.db.beans.Country;
import by.bsu.touragency.db.beans.Eat;
import by.bsu.touragency.db.beans.Hotel;
import by.bsu.touragency.db.beans.People;
import by.bsu.touragency.db.beans.Star;
import by.bsu.touragency.db.beans.Tour;
import by.bsu.touragency.db.beans.Transfer;
import by.bsu.touragency.db.beans.Transport;
import by.bsu.touragency.db.beans.TransportType;
import by.bsu.touragency.db.dao.CityDAO;
import by.bsu.touragency.db.dao.CountryDAO;
import by.bsu.touragency.db.dao.EatDAO;
import by.bsu.touragency.db.dao.HotelDAO;
import by.bsu.touragency.db.dao.PeopleDAO;
import by.bsu.touragency.db.dao.StarDAO;
import by.bsu.touragency.db.dao.TourDAO;
import by.bsu.touragency.db.dao.TransferDAO;
import by.bsu.touragency.db.dao.TransportDAO;
import by.bsu.touragency.db.dao.TransportTypeDAO;

public class AddSetTourInfoLogic {

	private static Logger logger = Logger.getLogger("log");

	private String errorMessage;

	private String tourId;
	private String tourTime;

	private String hotelId;
	private String hotelName;
	private String hotelAbout;
	private String cityName;

	private String peopleId;
	private String adultsNum;
	private String childrenNum;

	private String transportId;
	private String transportTimeFrom;
	private String transportTimeTo;
	private String transportCityFrom;
	private String mealType;
	private String countryName;
	private String countryFrom;
	private String starType;
	private String transportTypeStr;
	private String transportNumber;

	private String price;
	private String quantity;

	private String transferId;
	private String transferTimeFrom;
	private String transferTimeTo;

	private GregorianCalendar dateTo;
	private GregorianCalendar dateFrom;

	private Tour tour;
	private Hotel hotel;
	private City city;
	private Country country;
	private Eat eat;
	private Star star;
	private People people;
	private TransportType transportType;
	private City cityfrom;
	private Transport transport;
	private Country countryfrom;
	private Transfer transfer;

	private GregorianCalendar transferDateTo;
	private GregorianCalendar transferDateFrom;

	public AddSetTourInfoLogic(String hotelName, String hotelAbout,
			String cityName, String adultsNum, String childrenNum,
			String transportCityFrom, String mealType, String countryName,
			String countryFrom, String starType, String transportTypeStr,
			String transportNumber, String price, String quantity,
			String hotelId, String peopleId, String tourId, String transportId,
			String transferId, String transferTimeFrom, String tourTime,
			String transferTimeTo, String transportTimeFrom,
			String transportTimeTo) {
		super();
		this.tourId = tourId;
		this.tourTime = tourTime;

		this.hotelId = hotelId;
		this.hotelName = hotelName;
		this.hotelAbout = hotelAbout;
		this.cityName = cityName;

		this.peopleId = peopleId;
		this.adultsNum = adultsNum;
		this.childrenNum = childrenNum;

		this.transportId = transportId;
		this.transportTimeFrom = transportTimeFrom;
		this.transportTimeTo = transportTimeTo;
		this.transportCityFrom = transportCityFrom;
		this.mealType = mealType;
		this.countryName = countryName;
		this.countryFrom = countryFrom;
		this.starType = starType;
		System.out.println("logic" + transportTypeStr);
		this.transportTypeStr = transportTypeStr;
		this.transportNumber = transportNumber;

		this.price = price;
		this.quantity = quantity;

		this.transferId = transferId;
		this.transferTimeFrom = transferTimeFrom;
		this.transferTimeTo = transferTimeTo;
	}

	public String getErrorMessage() {
		return errorMessage;
	}

	public boolean isValidHotelAndPeople() {

		initialization();

		CountryDAO countryfromdao = new CountryDAO();
		TransferDAO transferdao = new TransferDAO();
		TransportDAO transportdao = new TransportDAO();
		TransportTypeDAO transportTypedao = new TransportTypeDAO();
		CityDAO cityfromdao = new CityDAO();
		HotelDAO hoteldao = new HotelDAO();
		CityDAO citydao = new CityDAO();
		CountryDAO countrydao = new CountryDAO();
		EatDAO eatdao = new EatDAO();
		PeopleDAO peopledao = new PeopleDAO();
		StarDAO stardao = new StarDAO();

		/* Tour */
		if (!tourGetDates())
			return false;

		/* People */
		if (!peopleGetInt())
			return false;

		/* Transport */
		if (!transportGetDates())
			return false;

		/* Transfer */
		if (!transferGetDates())
			return false;

		/* Price */
		if (!getPrice())
			return false;
		/* Quantity */
		if (!getQuantity())
			return false;

		logger.debug("Valid data");

		if (tour.getId() != 0) {
			/* set tour */
			/* Updates tour quantity,price */
			Tour oldTour = new Tour();
			TourDAO oldTourdao = new TourDAO();
			oldTour = oldTourdao.readById(tour.getId());

			if (oldTour.getQuantity() != tour.getQuantity()) {
				TourDAO tourdao = new TourDAO();
				tourdao.updateQuantity(tour);
			}
			if (oldTour.getPrice() != tour.getPrice()) {
				TourDAO tourdao = new TourDAO();
				tourdao.updatePrice(tour);
			}

			/* Updates hotel mealId,peopleId,about hotel */

			hotel = hoteldao.readById(hotel.getId());

			hotel.setAbout(hotelAbout);

			eat.setType(mealType);
			eat = eatdao.create(eat);
			hotel.setEat(eat);

			people = peopledao.create(people);
			hotel.setPeople(people);

			hoteldao.update(hotel);

			/* Updates transport */
			Transport oldtransport = new Transport();
			TransportDAO oldtransportdao = new TransportDAO();
			transportdao = new TransportDAO();
			oldtransport = oldtransportdao.readById(transport.getId());

			transport.setCityFrom(oldtransport.getCityFrom());
			transport.setCityTo(oldtransport.getCityTo());

			transportType.setNumber(transportNumber);
			transportType.setName(transportTypeStr);
			transportType = transportTypedao.create(transportType);

			transport.setView(transportType);

			transport = transportdao.create(transport);

			if (transport.getId() != oldtransport.getId()) {
				/* new transport */
				oldtransportdao.deleteById(oldtransport.getId());
				/* Updates tour transport */
				TourDAO tourdao = new TourDAO();
				tour.setTransport(transport);
				tourdao.updateTransport(tour);
			}/* can not be updated */

			/* Updates transfer */
			Transfer oldtransfer = new Transfer();
			TransferDAO oldtransferdao = new TransferDAO();
			transferdao = new TransferDAO();
			oldtransfer = oldtransferdao.readByID(transfer.getId());
			transfer.setCity(oldtransfer.getCity());
			transfer.setDateFrom(transferDateFrom);
			transfer.setDateTo(transferDateTo);

			transfer = transferdao.create(transfer);

			if (transfer.getId() != oldtransfer.getId()) {
				/* new transfer */
				oldtransferdao.deleteById(oldtransfer.getId());
				/* Updates tour transfer */
				TourDAO tourdao = new TourDAO();
				tour.setTransfer(transfer);
				tourdao.updateTransfer(tour);
			}/* can not be updated */

		} else {
			/* add tour */
			if (eat.isValidMealType(mealType)) {
				if (star.isValidStarType(starType)) {
					if (city.isValidCityName(cityName)) {
						if (country.isValidCountryName(countryName)) {
							if (countryfrom.isValidCountryName(countryFrom)) {
								if (cityfrom.isValidCityName(transportCityFrom)) {
									country = countrydao.create(country);

									city.setCountry(country);
									city = citydao.create(city);

									eat = eatdao.create(eat);

									people = peopledao.create(people);

									star = stardao.create(star);

									hotel.setName(hotelName);
									hotel.setCity(city);
									hotel.setEat(eat);
									hotel.setPeople(people);
									hotel.setStar(star);
									hotel.setAbout(hotelAbout);
									hoteldao.create(hotel);

									transportType.setName(transportTypeStr);
									transportType.setNumber(transportNumber);
									transportType = transportTypedao
											.create(transportType);

									countryfrom = countryfromdao
											.create(countryfrom);
									cityfrom.setCountry(countryfrom);

									cityfrom = cityfromdao.create(cityfrom);

									transport.setView(transportType);
									transport.setCityFrom(cityfrom);
									transport.setCityTo(city);
									transport.setDateFrom(dateFrom);
									transport.setDateTo(dateTo);

									transport = transportdao.create(transport);

									tour.setTransport(transport);

									transfer.setCity(city);
									transfer.setDateFrom(transferDateFrom);
									transfer.setDateTo(transferDateTo);
									transfer = transferdao.create(transfer);

									tour.setTransfer(transfer);

									tour.setHotel(hotel);

									tour.setDateTo(dateTo);
									tour.setDateFrom(dateFrom);

									TourDAO td = new TourDAO();
									tour = td.create(tour);

								}
								errorMessage += "Wrong Your City name";
								logger.error("Wrong Your Country type");
								return false;

							}
							errorMessage += "Wrong Your County name";
							logger.error("Wrong Your Country type");
							return false;
						}
						errorMessage += "Wrong Country name";
						logger.error("Wrong Country name");
						return false;
					}
					errorMessage += "Wrong City name";
					logger.error("Wrong City name");
					return false;
				}
				errorMessage += "Wrong Star type";
				logger.error("Wrong Star type");
				return false;
			}
			errorMessage += "Wrong Meal type";
			logger.error("Wrong Meal type");
			return false;

		}
		return true;
	}

	public void setErrorMessage(String errorMessage) {
		this.errorMessage = errorMessage;
	}

	public Tour getTour() {
		return tour;
	}

	public void setTour(Tour tour) {
		this.tour = tour;
	}

	private boolean transferGetDates() {
		String delim = " >-:";
		StringTokenizer st = new StringTokenizer(transferTimeTo, delim);
		int year = 0;
		int month = 0;
		int day = 0;
		int hour = 0;
		int minute = 0;
		if (transferTimeTo != "" && transferTimeTo != null) {
			year = Integer.parseInt(st.nextToken());
			month = Integer.parseInt(st.nextToken());
			day = Integer.parseInt(st.nextToken());
			hour = Integer.parseInt(st.nextToken());
			minute = Integer.parseInt(st.nextToken());
		} else {
			errorMessage += "Wrong date_to in TRANSFER part";
			logger.error("Wrong date_to in TRANSFER part");
			return false;
		}

		transferDateTo = (new GregorianCalendar(year, month, day, hour, minute));
		st = new StringTokenizer(transferTimeFrom, delim);

		year = 0;
		month = 0;
		day = 0;
		hour = 0;
		minute = 0;
		if (transferTimeFrom != "" && transferTimeFrom != null) {
			year = Integer.parseInt(st.nextToken());
			month = Integer.parseInt(st.nextToken());
			day = Integer.parseInt(st.nextToken());
			hour = Integer.parseInt(st.nextToken());
			minute = Integer.parseInt(st.nextToken());
		} else {
			errorMessage += "Wrong date_from TRANSFER part";
			logger.error("Wrong date_from in TRANSFER part");
			return false;
		}
		transferDateFrom = (new GregorianCalendar(year, month, day, hour,
				minute));
		if (!transferDateFrom.before(transferDateTo)) {
			errorMessage += "Date_to should be after Date_from";
			logger.error("Date_to should be after Date_from");
			return false;
		}

		return true;
	}

	private boolean getQuantity() {
		Scanner sc = new Scanner(quantity);
		int quantityint = 0;
		if (quantity != "" && quantity != null)
			quantityint = sc.nextInt();
		else {
			errorMessage += "Warning: wrong quantity";
			logger.warn("Wrong quantity");
			return false;
		}
		if (tour.setQuantity(quantityint))
			return true;
		else
			return false;
	}

	private boolean getPrice() {
		Scanner sc = new Scanner(price);
		int priceint = 0;
		if (price != "" && price != null)
			priceint = sc.nextInt();
		else {
			errorMessage += "Warning: wrong price";
			logger.warn("Wrong price");
			return false;
		}
		if (tour.setPrice(priceint)) {
			return true;
		} else
			return false;
	}

	private boolean tourGetDates() {
		String delim = " >-:";
		int year = 0;
		int month = 0;
		int day = 0;
		int hour = 0;
		int minute = 0;
		StringTokenizer st = new StringTokenizer(tourTime, delim);
		if (tourTime != "" && tourTime != null) {
			year = Integer.parseInt(st.nextToken());
			month = Integer.parseInt(st.nextToken());
			day = Integer.parseInt(st.nextToken());
			hour = Integer.parseInt(st.nextToken());
			minute = Integer.parseInt(st.nextToken());
			tour.setDateTo(new GregorianCalendar(year, month, day, hour, minute));
			year = Integer.parseInt(st.nextToken());
			month = Integer.parseInt(st.nextToken());
			day = Integer.parseInt(st.nextToken());
			hour = Integer.parseInt(st.nextToken());
			minute = Integer.parseInt(st.nextToken());
			tour.setDateFrom(new GregorianCalendar(year, month, day, hour,
					minute));
			return true;
		} else {
			errorMessage += "Wrong date_to in TRANSFER part";
			logger.error("Wrong date_to in TRANSFER part");
			return false;
		}

	}

	private boolean transportGetDates() {
		String delim = " >-:";
		StringTokenizer st = new StringTokenizer(transportTimeTo, delim);
		int year = 0;
		int month = 0;
		int day = 0;
		int hour = 0;
		int minute = 0;
		if (transportTimeTo != "" && transportTimeTo != null) {
			year = Integer.parseInt(st.nextToken());
			month = Integer.parseInt(st.nextToken());
			day = Integer.parseInt(st.nextToken());
			hour = Integer.parseInt(st.nextToken());
			minute = Integer.parseInt(st.nextToken());
		} else {
			errorMessage += "Wrong date_to TRANPORT part";
			logger.error("Wrong date_to in TRANSPORT part");
			return false;
		}

		dateTo = new GregorianCalendar(year, month, day, hour, minute);
		st = new StringTokenizer(transportTimeFrom, delim);
		year = 0;
		month = 0;
		day = 0;
		hour = 0;
		minute = 0;
		if (transportTimeFrom != "" && transportTimeFrom != null) {
			year = Integer.parseInt(st.nextToken());
			month = Integer.parseInt(st.nextToken());
			day = Integer.parseInt(st.nextToken());
			hour = Integer.parseInt(st.nextToken());
			minute = Integer.parseInt(st.nextToken());
		} else {
			errorMessage += "Wrong date_from TRANPORT part";
			logger.error("Wrong date_from in TRANSPORT part");
			return false;
		}
		dateFrom = new GregorianCalendar(year, month, day, hour, minute);

		if (dateFrom.before(dateTo)) {
			transport.setDateFrom(dateFrom);
			transport.setDateTo(dateTo);
		} else {
			errorMessage += "Date_to should be after Date_from";
			logger.error("Date_to should be after Date_from");
			return false;
		}
		return true;
	}

	private boolean peopleGetInt() {
		Scanner sc = new Scanner(adultsNum);
		int adults = 0;
		if (adultsNum != "" && adultsNum != null)
			adults = sc.nextInt();
		sc = new Scanner(childrenNum);
		int children = 0;
		if (childrenNum != "" && childrenNum != null)
			children = sc.nextInt();

		if (!(people.setAdults(adults) && people.setChildren(children))) {
			errorMessage += "Number of children or adults is wrong";
			logger.error("Number of children or adults is wrong");
			return false;
		}
		return true;
	}

	private void initialization() {

		hotel = new Hotel();
		eat = new Eat();
		city = new City();
		country = new Country();
		people = new People();
		star = new Star();
		tour = new Tour();
		transport = new Transport();
		transportType = new TransportType();
		cityfrom = new City();
		countryfrom = new Country();
		transfer = new Transfer();

		hotel.setId(getInt(hotelId));
		tour.setId(getInt(tourId));
		people.setId(getInt(peopleId));
		transfer.setId(getInt(transferId));
		System.out.println("logic" + transfer.getId());
		transport.setId(getInt(transportId));

		errorMessage = "";

	}

	private int getInt(String string) {
		Scanner sc = new Scanner(string);
		int x = 0;
		if (string != "" && string != null)
			x = sc.nextInt();
		return x;
	}

	public void setTransferDateTo(GregorianCalendar transferDateTo) {
		this.transferDateTo = transferDateTo;
	}

	public GregorianCalendar getTransferDateTo() {
		return transferDateTo;
	}

	public void setTransferDateFrom(GregorianCalendar transferDateFrom) {
		this.transferDateFrom = transferDateFrom;
	}

	public GregorianCalendar getTransferDateFrom() {
		return transferDateFrom;
	}

}
